package com.cy.pj.goods.dao;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import javax.sql.DataSource;
import java.lang.reflect.MalformedParameterizedTypeException;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/*
* 数据访问层对象的具体实现，在实现类中借助JDBC直接访问数据库
* @Repository是spring框架中定义一个描述bean对象的注解
* */

@Repository
public class DefaultGoodsDao implements GoodsDao{

    @Autowired
    private DataSource dataSource;

    //初始化一个日志对象
    private static final Logger log= LoggerFactory.getLogger(DefaultGoodsDao.class);

    //行映射
    Map<String, Object>rowMap(ResultSetMetaData rsmd,ResultSet res)throws SQLException{
        Map<String,Object> map=new HashMap<>();
        for (int i=1;i<=rsmd.getColumnCount();i++){  //循取出所有字段的值
            map.put(rsmd.getColumnName(i), res.getObject(rsmd.getColumnName(i)));
        }
        return map;
    }

    //释放资源
    public void close(ResultSet res,Statement stmt,Connection conn){
        if(res!=null){ try{ res.close(); }catch (SQLException e1){ } }
        if(stmt!=null){ try{ stmt.close(); }catch (SQLException e1){ } }
        if(conn!=null){ try{ conn.close(); }catch (SQLException e1){ } }
    }

    @Override
    public List<Map<String, Object>> findGoods() {

        Connection conn=null;
        Statement stmt=null;
        String sql="select * from   tb_goods";
        ResultSet res=null;

        try {
            //1。获取链接
            conn = dataSource.getConnection();

            //2.创建Statement
            stmt = conn.createStatement();

            //3.发送sql
            res = stmt.executeQuery(sql);

            //4.处理结果
            List<Map<String,Object>> list=new ArrayList<>();

            ResultSetMetaData rsmd=res.getMetaData();   //获取结果集中的元数据，即描述数据的数据



            while (res.next()) {  //循环一次取一次,这个过程通常称之为行映射
                /*Map<String, Object> map = new HashMap<>();
                map.put("id", res.getInt("id"));
                map.put("name", res.getString("name"));
                map.put("remark", res.getString("remark"));
                map.put("createdTime", res.getTimestamp("createdTime"));
                list.add(map);*/

                //映射方案2
                list.add(rowMap(rsmd, res));
            }
            return list;
        }catch (SQLException e){
            e.printStackTrace();
            log.info("查询异常,{}",e.getMessage());
            //return null;
            throw new RuntimeException("数据查询失败"+e.getMessage());

        }finally {
            close(res,stmt,conn);
        }





    }
}

/*
对于如上查询商品数据的过程有什么优缺点？
    优点：
    1）代码简单
    2）使用了连接池，优化了建立连接的过程，从池中获取链接，提高了数据访问性能
    3）使用了map映射，简化了pojo对象定义


    缺点：
    1）可重用性比较差（例如资源释放代码，完全可以封装）
    2）行映射不够灵活，过于僵硬
    3）异常的处理不能简单打印一下，然后返回一个null就行了
    4）Map封装数据时值类型不可控（建议后续改为pojo对象）
    5）对共性模板应该进行封装，特性代码进行提取
 */
